package com.xls.pet.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.xls.pet.entity.Category;
import com.xls.pet.entity.Item;
import com.xls.pet.entity.ItemStock;
import com.xls.pet.mapper.CategoryMapper;
import com.xls.pet.mapper.ItemStockMapper;
import com.xls.pet.mapper.ItemMapper;
import com.xls.pet.query.ItemStockQuery;
import com.xls.pet.service.ItemStockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Objects;

import static com.xls.pet.entity.table.CategoryTableDef.CATEGORY;
import static com.xls.pet.entity.table.ItemStockTableDef.ITEM_STOCK;
import static com.xls.pet.entity.table.ItemTableDef.ITEM;

/**
 * 服务层实现。
 *
 * @author xls
 * @since 2024-06-17
 */
@Service
public class ItemStockServiceImpl extends ServiceImpl<ItemStockMapper, ItemStock> implements ItemStockService {

    @Autowired
    ItemStockMapper itemStockMapper;

    @Autowired
    ItemMapper itemMapper;
    @Autowired
    private CategoryMapper categoryMapper;

    @Override
    public Page<ItemStock> list(Integer pageNumber, Integer pageSize, Integer totalRow, ItemStockQuery itemStockQuery) {
        QueryChain<ItemStock> queryChain = QueryChain.of(itemStockMapper)
                .select(
                        ITEM_STOCK.DEFAULT_COLUMNS,
                        ITEM.DEFAULT_COLUMNS
                )
                .from(ITEM_STOCK)
                .join(ITEM).on(ITEM_STOCK.ITEM_ID.eq(ITEM.ID));
        if (itemStockQuery.getCategoryId() != null) {
            List<Integer> idList = categoryMapper.getchildCategoryIdList(itemStockQuery.getCategoryId());
            queryChain.join(CATEGORY).on(ITEM.CATEGORY_ID.eq(CATEGORY.ID)).and(CATEGORY.ID.in(idList));
        }
        if (itemStockQuery.getItemId() != null) {
            queryChain.where(ITEM_STOCK.ITEM_ID.eq(itemStockQuery.getItemId()));
        }
        if (itemStockQuery.getDateRule() != null) {
            itemStockQuery.setBeginAndEnd(itemStockQuery.getDateRule());
        }
        if (itemStockQuery.getExpirationDateBegin() != null) {
            queryChain.where(ITEM_STOCK.EXPIRATION_DATE.ge(itemStockQuery.getExpirationDateBegin()));
        }
        if (itemStockQuery.getExpirationDateEnd() != null) {
            queryChain.where(ITEM_STOCK.EXPIRATION_DATE.le(itemStockQuery.getExpirationDateEnd()));
        }
        if (itemStockQuery.getQuantity() != null) {
            if (itemStockQuery.getQuantity() == 1) {
                queryChain.where(ITEM_STOCK.QUANTITY.gt(0));
            } else {
                queryChain.where(ITEM_STOCK.QUANTITY.eq(0));
            }
        }
        queryChain.orderBy(ITEM_STOCK.EXPIRATION_DATE.asc());
        QueryWrapper queryWrapper = queryChain.toQueryWrapper();
        Page<ItemStock> itemStockPage = this.page(Page.of(pageNumber, pageSize, totalRow), queryWrapper);
        List<ItemStock> itemStockList = itemStockPage.getRecords();
        List<Category> categoryList = categoryMapper.selectAll();
        itemStockList.forEach(itemStock -> {
            categoryMapper.setCategoryName(categoryList, itemStock.getItem());
            // 计算剩余天数百分比
            int percentage = new BigDecimal(itemStock.getRemainingDays())
                    .divide(new BigDecimal(ChronoUnit.DAYS.between(itemStock.getProductDate().toLocalDate(),
                            itemStock.getExpirationDate().toLocalDate())), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).intValue();
            itemStock.setPercentage(Math.max(percentage, 0));
        });
        return itemStockPage;
    }

    @Override
    public void saveItemStock(ItemStock itemStock) {
        Item item = itemMapper.selectOneById(itemStock.getItemId());
        itemStock.calculateExpirationDate(item.getUnit(), item.getShelfLife());
        this.save(itemStock);
    }

    @Override
    public void updateItemStock(ItemStock itemStock) {
        ItemStock oldItemStock = itemStockMapper.selectOneById(itemStock.getId());
        if (!Objects.equals(itemStock.getProductDate(), oldItemStock.getProductDate())) {
            Item item = itemMapper.selectOneById(itemStock.getItemId());
            itemStock.calculateExpirationDate(item.getUnit(), item.getShelfLife());
        }
        this.updateById(itemStock);
    }
}
